/*
-----------------------------------------------------------------------------
This source file is part of the
   ___                 __    __ _ _    _ 
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/                              
      Tutorial Framework
      http://www.ogre3d.org/tikiwiki/
-----------------------------------------------------------------------------
*/
#include "GameApp.h"
#include "CollisionDetection.h"
#include <OgreStringConverter.h>


//-------------------------------------------------------------------------------------
GameApp::GameApp(void)
{
}
//-------------------------------------------------------------------------------------
GameApp::~GameApp(void)
{
}
//-------------------------------------------------------------------------------------
<<<<<<< .mine
void GameApp::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
	miniMap->setVisible(false);
}
void GameApp::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
	miniMap->setVisible(true);
}
=======
void GameApp::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
	// hide plane before rendering
	mPlaneEnt->setVisible(false);
}
void GameApp::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
	// show plane after rendering
	mPlaneEnt->setVisible(true);
}

>>>>>>> .r66
void GameApp::createScene(void)
{
	// Set the ambient light
	mSceneMgr->setAmbientLight(Ogre::ColourValue::White);
//-------------------------------------------------------------------------------------	
/*------
* Camera
-------*/

	mCamera->setPosition(0, 30, 0);
	mCamera->lookAt(0, 30, 0);
	mCamNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("CameraNode");
	mCamNode->attachObject(mCamera);


#pragma region object

	// Create a box
	object		= mSceneMgr->createEntity("Box", "HideAndSeekBox.mesh");
	object->setMaterialName("HideAndSeekShader/Cube");
	objectNode	= mCamNode->createChildSceneNode("PlayerNode");
	objectNode->setPosition(0.0, 6.0, 0.0);
	objectNode->attachObject(object);

#pragma endregion object

#pragma region rtt

	// Create floor object
//	floor	= mSceneMgr->createEntity("Floor", "HideAndSeekPlane.mesh");
//	floorNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
//	floorNode->showBoundingBox(true);
//	floorNode->attachObject(floor);

	mPlane = new Ogre::MovablePlane("Plane");
	mPlane->d = 0;
	mPlane->normal = Ogre::Vector3::UNIT_Y;
	Ogre::MeshManager::getSingleton().createPlane("PlaneMesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
		*mPlane, 450, 450, 1, 1, true, 1, 1, 1, Ogre::Vector3::UNIT_Z);
	mPlaneEnt = mSceneMgr->createEntity("PlaneEntity", "PlaneMesh");
	mPlaneEnt->setMaterialName("PlaneMat");
	mPlaneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	mPlaneNode->attachObject(mPlaneEnt);

	// Create a texture
	Ogre::TexturePtr rttTex =
		Ogre::TextureManager::getSingleton().createManual("RttTex",
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512,
		512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
	{
	// Get a render target of this texture
	Ogre::RenderTarget* rt = rttTex->getBuffer()->getRenderTarget();

	// Create a reflection camera (does exactly what the mCamera does... for now)
	reflectionCam = mSceneMgr->createCamera("ReflectionCam");
	reflectionCam->setNearClipDistance(mCamera->getNearClipDistance());
	reflectionCam->setFarClipDistance(mCamera->getFarClipDistance());
	reflectionCam->setAspectRatio(mWindow->getViewport(0)->getActualWidth()/mWindow->getViewport(0)->getActualHeight());
	rt->addListener(this);

	// add a viewport to the reflection camera
	Ogre::Viewport* vp = rt->addViewport(reflectionCam);
	vp->setClearEveryFrame(true);
	vp->setBackgroundColour(Ogre::ColourValue::Black);
	vp->setOverlaysEnabled(false); // disable for when CEGUI stuff is implemented

	// store render texture in a file - update first
	rt->setAutoUpdated(true);
	// write
//	rt->writeContentsToFile("rttImg");

<<<<<<< .mine

	// Create a 2D rectangle "mini map"
	// Generate Texture Coords
	miniMap = new Ogre::Rectangle2D(true);
	// Set corners of rect: Left = -1.0, Top = +1.0, Right = +1.0, Bttm = -1.0
	// Set to 1.0, -1.0, 0.5, -0.5 to make the rect upside down
	miniMap->setCorners(-1.0f, 1.0f, -0.5f, 0.5f);
	// Give it an large AABB to prevent culling when not facing scene node
	miniMap->setBoundingBox(Ogre::AxisAlignedBox(-100000.0f *
		Ogre::Vector3::UNIT_SCALE, 100000.0f * Ogre::Vector3::UNIT_SCALE));
	// Attach to scene node
	Ogre::SceneNode* miniMapNode =
		mSceneMgr->getRootSceneNode()->createChildSceneNode("MiniMapNode");
	miniMapNode->attachObject(miniMap);


	// Create material for the RenderTexture to then show on the target
	Ogre::MaterialPtr rttMat =
=======
	// Create material to use on floor
	Ogre::MaterialPtr mat =
>>>>>>> .r66
		Ogre::MaterialManager::getSingleton().create("RttMat",
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
<<<<<<< .mine
=======
	Ogre::TextureUnitState* tusTex = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RustedMetal.jpg");
	tusTex = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex");
	// Blend with base texture
	tusTex->setColourOperationEx(Ogre::LBX_BLEND_MANUAL, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT,
		Ogre::ColourValue::White, Ogre::ColourValue::White, 0.25);
	tusTex->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	tusTex->setProjectiveTexturing(true, reflectionCam);
	
//	floor->setMaterial(mat);
	rt->addListener(this);
>>>>>>> .r66

<<<<<<< .mine
	Ogre::Technique* matTechnique = rttMat->createTechnique();
	matTechnique->createPass();
	rttMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
	rttMat->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex");

	// Apply Texture to mini map
	miniMap->setMaterial("RttMat");

	// Create floor object
	floor	= mSceneMgr->createEntity("Floor", "HideAndSeekPlane.mesh");
	floor->setMaterialName("HideAndSeekShader/Glass");
	floorNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	floorNode->showBoundingBox(true);
	floorNode->attachObject(floor);

=======
	reflectionCam->enableReflection(mPlane);
	reflectionCam->enableCustomNearClipPlane(mPlane);
	}
	mPlaneEnt->setMaterialName("RttMat");
>>>>>>> .r66
#pragma endregion rtt
}

bool GameApp::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	return BaseApplication::frameRenderingQueued(evt);
}

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
    int main(int argc, char *argv[])
#endif
    {
        // Create application object
        GameApp app;

        try {
            app.go();
        } catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
            std::cerr << "An exception has occured: " <<
                e.getFullDescription().c_str() << std::endl;
#endif
        }

        return 0;
    }

#ifdef __cplusplus
}
#endif
